package thesis.ramstorage.core;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import thesis.ramstorage.application.DataObj;

public class PhysicalNode extends Node {

//    Set<Long> virtualNodeIds = new HashSet<Long>();
    private long numberOfVirtualNode; //number of virtual node
    private long capacity;//number of dataObj can be hold
    private long ID;
    private final Map<Long, SortedMap<Long, DataObj>> store = new TreeMap<Long, SortedMap<Long, DataObj>>();
    public PhysicalNode() {
    }

    
    public int getState() {
        // TODO Auto-generated method stub
        return super.getState();
    }

    public void setState(int state) {
        // TODO Auto-generated method stub
        super.setState(state);
    }

    public synchronized void flush(){
        this.store.clear();
    }

    public synchronized void terminate() {
//          virtualNodeIds.clear();
        //export to file and store information
        //load again if node join again
        for(long k : this.store.keySet()){
            this.store.get(k).clear();
        }
//        store.clear();
    }

    public boolean overload() {
        return (this.state == Fallible.OVERLOAD);
    }

    public void run() {
        // TODO Auto-generated method stub
    }

    public synchronized long getNumberOfVirtualNode() {
        return numberOfVirtualNode;
    }

    public void setNumberOfVirtualNode(long numberOfVirtualNode) {
        this.numberOfVirtualNode = numberOfVirtualNode;
    }

    public long getID() {
        return ID;
    }

    public void setID(long id) {
        ID = id;
    }

    public Set<Long> getVirtualNodeIds() {
        synchronized(this){
            return store.keySet();
        }
    }

//    public void setVirtualNodeIds(Set<Long> virtualNodeIds) {
//        this.virtualNodeIds = virtualNodeIds;
//    }

    public long getCapacity() {
        return capacity;
    }

    public void setCapacity(long capacity) {
        this.capacity = capacity;
    }

    public synchronized long getLoad() {
        // TODO Auto-generated method stub
        long res = 0;
        for(long k : this.store.keySet()){
            res += this.store.get(k).size();
        }
        return res;
    }

    public int compareTo(Node arg0) {
        // TODO Auto-generated method stub
        return this.getID() <= arg0.getID() ? 1 : -1;
    }

    public String put(long vNodeId, long dataId, DataObj dataObj){
//        this.store.put(id, dataObj);
        SortedMap<Long, DataObj> vNodeStore = this.store.get(vNodeId);
        if(vNodeStore == null){
            vNodeStore = new TreeMap<Long, DataObj>();
            this.store.put(vNodeId, vNodeStore);
        }
        vNodeStore.put(dataId, dataObj);
        return "OK";
    }

    public DataObj get(long vNodeId, long dataId){
         Map<Long, DataObj> vNodeStore = this.store.get(vNodeId);
         return vNodeStore.get(dataId);
    }
    public synchronized void remove(long vNodeId, Long storedKey) {
         Map<Long, DataObj> vNodeStore = this.store.get(vNodeId);
         vNodeStore.remove(storedKey);
    }

    public synchronized List<Long> listKeys(long vNodeId){
//        return new ArrayList<Long>(this.store.tailMap(id).keySet());
        return new ArrayList<Long>(this.store.get(vNodeId).keySet());
        //need to recheck
    }

    public synchronized  void startUp(){
    }
}
